﻿// Decompiled with JetBrains decompiler
// Type: Bannerlord.ModuleManager.ModuleSorter
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using System;
using System.Collections.Generic;
using System.Linq;

#nullable enable
namespace Bannerlord.ModuleManager
{
  internal static class ModuleSorter
  {
    public static IList<ModuleInfoExtended> Sort(IReadOnlyCollection<ModuleInfoExtended> source)
    {
      ModuleInfoExtended[] correctModules = source.Where<ModuleInfoExtended>((Func<ModuleInfoExtended, bool>) (x => ModuleUtilities.AreDependenciesPresent(source, x))).OrderByDescending<ModuleInfoExtended, bool>((Func<ModuleInfoExtended, bool>) (x => x.IsOfficial)).ThenByDescending<ModuleInfoExtended, string>((Func<ModuleInfoExtended, string>) (mim => mim.Id), (IComparer<string>) new AlphanumComparatorFast()).ToArray<ModuleInfoExtended>();
      return ModuleSorter.TopologySort<ModuleInfoExtended>((IEnumerable<ModuleInfoExtended>) correctModules, (Func<ModuleInfoExtended, IEnumerable<ModuleInfoExtended>>) (module => ModuleUtilities.GetDependencies((IReadOnlyCollection<ModuleInfoExtended>) correctModules, module)));
    }

    public static IList<ModuleInfoExtended> Sort(
      IReadOnlyCollection<ModuleInfoExtended> source,
      ModuleSorterOptions options)
    {
      ModuleInfoExtended[] correctModules = source.Where<ModuleInfoExtended>((Func<ModuleInfoExtended, bool>) (x => ModuleUtilities.AreDependenciesPresent(source, x))).OrderByDescending<ModuleInfoExtended, bool>((Func<ModuleInfoExtended, bool>) (x => x.IsOfficial)).ThenByDescending<ModuleInfoExtended, string>((Func<ModuleInfoExtended, string>) (mim => mim.Id), (IComparer<string>) new AlphanumComparatorFast()).ToArray<ModuleInfoExtended>();
      return ModuleSorter.TopologySort<ModuleInfoExtended>((IEnumerable<ModuleInfoExtended>) correctModules, (Func<ModuleInfoExtended, IEnumerable<ModuleInfoExtended>>) (module => ModuleUtilities.GetDependencies((IReadOnlyCollection<ModuleInfoExtended>) correctModules, module, options)));
    }

    public static IList<T> TopologySort<T>(
      IEnumerable<T> source,
      Func<T, IEnumerable<T>> getDependencies)
    {
      List<T> list = new List<T>();
      HashSet<T> visited = new HashSet<T>();
      foreach (T obj in source)
        ModuleSorter.Visit<T>(obj, getDependencies, (Action<T>) (item => list.Add(item)), visited);
      return (IList<T>) list;
    }

    public static void Visit<T>(
      T item,
      Func<T, IEnumerable<T>> getDependencies,
      Action<T> addItem,
      HashSet<T> visited)
    {
      if (visited.Contains(item))
        return;
      visited.Add(item);
      IEnumerable<T> objs = getDependencies(item);
      if (objs != null)
      {
        foreach (T obj in objs)
          ModuleSorter.Visit<T>(obj, getDependencies, addItem, visited);
      }
      addItem(item);
    }
  }
}
